home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c++-part2 / 16656 < prev    next >
Encoding:
Text File  |  1996-08-05  |  8.2 KB  |  224 lines

  1. Path: hellwig.a2i!hellwig
  2. From: Oliver Hellwig <hellwig@rahul.net>
  3. Newsgroups: comp.lang.c++,comp.lang.c,comp.os.ms-windows.programmer.misc
  4. Subject: Re: fastest code
  5. Date: 11 Apr 1996 17:02:20 GMT
  6. Organization: a2i network
  7. Message-ID: <4kjdus$fiq@samba.rahul.net>
  8. References: <316112A2.7D37@public.sta.net.cn> <4kghs7$250@news1.mnsinc.com> <4kgu7g$n9a@solutions.solon.com> <4kh2p7INNkcq@keats.ugrad.cs.ubc.ca>
  9. NNTP-Posting-Host: waltz.rahul.net
  10. NNTP-Posting-User: hellwig
  11.  
  12. In article <4kh2p7INNkcq@keats.ugrad.cs.ubc.ca>,
  13. Kazimir Kylheku <c2a192@ugrad.cs.ubc.ca> wrote:
  14. >In article <4kgu7g$n9a@solutions.solon.com>,
  15. >Peter Seebach <seebs@solon.com> wrote:
  16. > >In article <4kghs7$250@news1.mnsinc.com>,
  17. > >Szu-Wen Huang <huang@mnsinc.com> wrote:
  18. > >>Peter Seebach (seebs@solutions.solon.com) wrote:
  19. > >>: In article <1996Apr10.110121.6784@friend.kastle.com>,
  20. > >>: Richard Krehbiel <rich@kastle.com> wrote:
  21. > >>: >Oliver Hellwig <hellwig@rahul.net> wrote:
  22. > >>: >>         for (i=0; i<16; i++)
  23. > >>: >>             prom[i] = prom[i+i];
  24. > >
  25. > >>: HUH?  the code as written has a clear effect, which is to shove all of
  26. > >>: the elements of an array over one.  It certainly is an optimizer bug.
  27. > >
  28. > >>: Read the code carefully; the 2nd reference to prom[] uses a different
  29. > >>: index into the array.  This is not a meaningless statement.
  30. > >
  31. > >>*You* read closely.  The second index is "i+i".  ;)  Okay, so it's a
  32. > >>typo, but one who says "read carefully" is expected to.  Cheers.
  33. > >
  34. > >Okay, so the code becomes undefined when i becomes 8.
  35. >
  36. >No it actually does not. The prom array is declared to be 32 elements wide (I
  37. >checked the code yesterday, the precise name is something like SA_prom), so
  38. >prom[16] is well defined, as is prom[30]. The purpose of the code is to
  39. >pack together array elements with even indices in an array of 32 elements;
  40. >the loop is correct.
  41. >
  42. >What happens is that these 32 bytes are read from a hardware register and
  43. >buffered. The code that reads them detects if they come in equivalent pairs and
  44. >sets a flag called ``wordlength'' accordingly. If they are in pairs, they have
  45. >to be squished, and the offending network card has to be sent a message to stop
  46. >doing that (according to my primitive understanding of the code).
  47. >
  48. >Secondly, volatile is not going to help. prom[] is not an lvalue representing a
  49. >memory mapped I/O region, or any storage that can unexpectedly change between
  50. >sequence points, but a perfectly ordinary auto variable.
  51. >
  52. > >And does nothing when i is 0.
  53. > >
  54. > >But the intervening few cases would be expected to produce
  55. > >assignments.
  56. > >
  57. > >I still think eliminating the assignments is a bug, and that "volatile"
  58. > >should not have any effect, but I'll grant that it's far
  59. > >from the only problem.
  60. >
  61. >Precisely. Volatile should have no effect here. The values of the array are
  62. >subsequently depended on by other code, so eliminating the values is incorrect.
  63. >
  64. >The compiler would have to be extremely smart to eliminate the ``compression''
  65. >loop and then split the subsequent code into two cases based on whether the
  66. >loop was or was not supposed to have happened (this depends on a single
  67. >variable ``wordlength'' that is set to either 1 or 2).  But the original poster
  68. >said that the compiler kept the loop anyway, just eliminated the assignments,
  69. >and it's doubtful that Watcom, or any other compiler, would do this sort of
  70. >optimization.
  71.  
  72. Well it did!  I did not turn on full optimizations but I just used the
  73. compiler in it's default mode.  However, when I turned off all optimizations
  74. then it compiled correctly.  I verified that it left the loop but removed
  75. the assignment by using the watcom supplied WDISASM.EXE which converts
  76. object files into assembly files (the watcom compiler does not have
  77. a switch to output directly to assembly).  I assumed that some people
  78. would just be able to verify this with their watcom compilers.
  79. However, I'm going to include my test program and the disassembly
  80. of that program which shows that the loop is still there.
  81.  
  82.  
  83. --------------------------file: bug.c--------------------------
  84. /*
  85.     This code demonstrates an optimizer bug with watcom 10.5
  86.  
  87.     complile with:  wcl386 bug.c
  88.  
  89.     The bug goes away when optimizations are disabled:
  90.           wcl386 -od bug.c
  91. */
  92. #include <stdio.h>
  93.  
  94. int
  95. main(void)
  96. {
  97.     unsigned char prom[32];
  98.     int i;
  99.  
  100.     for (i=0; i<32; i++)
  101.         prom[i] = i;
  102.  
  103.     printf("Initial array:\n\t");
  104.     for (i=0; i<16; i++)
  105.         printf("%d ", prom[i]);
  106.  
  107.     printf("\n");
  108.  
  109.     /* A disassembly will show that nothing has changed. */
  110.     /* This code comes from the linux ne2000 network driver, */
  111.     /*  its purpose is to compress the 32 doubled bytes down */
  112.     /*  to 16 bytes */
  113.     for (i=0; i<16; i++)
  114.         prom[i] = prom[i+i];
  115.  
  116.     printf("This array should only show even numbers:\n\t");
  117.     /* at this point the array is unchanged */
  118.     for (i=0; i<16; i++)
  119.         printf("%d ", prom[i]);
  120.  
  121.     printf("\n");
  122.  
  123.     return 0;
  124. }
  125.  
  126. ------------------------ file: bug.asm ----------------
  127.  
  128. .386p
  129.                 NAME    BUG
  130.                 EXTRN   _cstart_ :BYTE
  131.                 EXTRN   printf_ :BYTE
  132.                 EXTRN   __CHK :BYTE
  133. DGROUP          GROUP   CONST,CONST2,_DATA,_BSS
  134. _TEXT           SEGMENT BYTE PUBLIC USE32 'CODE'
  135.                 ASSUME  CS:_TEXT ,DS:DGROUP,SS:DGROUP
  136.                 PUBLIC  main_ 
  137. main_:          push    00000030H
  138.                 call    near ptr __CHK
  139.                 push    edx
  140.                 sub     esp,00000020H
  141.                 xor     edx,edx
  142. L1:             mov     byte ptr [esp+edx],dl
  143.                 inc     edx
  144.                 cmp     edx,00000020H
  145.                 jl      short L1
  146.                 push    offset DGROUP:L5
  147.                 call    near ptr printf_
  148.                 add     esp,00000004H
  149.                 xor     edx,edx
  150. L2:             xor     eax,eax
  151.                 mov     al,byte ptr [esp+edx]
  152.                 push    eax
  153.                 push    offset DGROUP:L6
  154.                 call    near ptr printf_
  155.                 add     esp,00000008H
  156.                 inc     edx
  157.                 cmp     edx,00000010H
  158.                 jl      short L2
  159.                 push    offset DGROUP:L7
  160.                 call    near ptr printf_
  161.                 add     esp,00000004H
  162.                 xor     edx,edx
  163. L3:             inc     edx
  164.                 cmp     edx,00000010H
  165.                 jl      short L3
  166.                 push    offset DGROUP:L8
  167.                 call    near ptr printf_
  168.                 add     esp,00000004H
  169.                 xor     edx,edx
  170. L4:             xor     eax,eax
  171.                 mov     al,byte ptr [esp+edx]
  172.                 push    eax
  173.                 push    offset DGROUP:L6
  174.                 call    near ptr printf_
  175.                 add     esp,00000008H
  176.                 inc     edx
  177.                 cmp     edx,00000010H
  178.                 jl      short L4
  179.                 push    offset DGROUP:L7
  180.                 call    near ptr printf_
  181.                 add     esp,00000004H
  182.                 xor     eax,eax
  183.                 add     esp,00000020H
  184.                 pop     edx
  185.                 ret     
  186. _TEXT           ENDS
  187.  
  188. CONST           SEGMENT DWORD PUBLIC USE32 'DATA'
  189. L5              DB      49H,6eH,69H,74H,69H,61H,6cH,20H
  190.                 DB      61H,72H,72H,61H,79H,3aH,0aH,09H
  191.                 DB      00H
  192. L6              DB      25H,64H,20H,00H
  193. L7              DB      0aH,00H
  194. L8              DB      54H,68H,69H,73H,20H,61H,72H,72H
  195.                 DB      61H,79H,20H,73H,68H,6fH,75H,6cH
  196.                 DB      64H,20H,6fH,6eH,6cH,79H,20H,73H
  197.                 DB      68H,6fH,77H,20H,65H,76H,65H,6eH
  198.                 DB      20H,6eH,75H,6dH,62H,65H,72H,73H
  199.                 DB      3aH,0aH,09H,00H
  200. CONST           ENDS
  201.  
  202. CONST2          SEGMENT DWORD PUBLIC USE32 'DATA'
  203. CONST2          ENDS
  204.  
  205. _DATA           SEGMENT DWORD PUBLIC USE32 'DATA'
  206. _DATA           ENDS
  207.  
  208. _BSS            SEGMENT DWORD PUBLIC USE32 'BSS'
  209. _BSS            ENDS
  210.  
  211.                 END
  212.  
  213. ---------------------end of bug.asm ------------------------
  214.  
  215. When you look at the loop at L3 you will notice that the loop
  216. is empty!  I just compiled this with "wcl386 bug.c".  It's possible
  217. that if I were to turn on full optimizations it might also remove
  218. the loop.  I didn't bother to try this because it didn't seem
  219. interesting to me.  I just want it to compile correct programs!
  220.  
  221. -- 
  222. Oliver Hellwig
  223. hellwig@rahul.net
  224.